package com.kehutong.tag.service;

import com.kehutong.common.DoveClient;
import com.kehutong.common.entity.Root;
import com.kehutong.crm.enums.TagSourceType;
import com.kehutong.tag.dao.UserTagDao;
import com.kehutong.tag.entity.CustomizeTag;
import com.kehutong.tag.entity.TemplateTag;
import org.coraframework.bean.Beans;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.PageCondition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 模板标签服务类
 *
 * @author: liukunlong
 * @date: 2021-07-28 10:08
 */
@WebService("/crm/template/tag/service")
public class TemplateTagService {

    static final Logger logger = LoggerFactory.getLogger(TemplateTagService.class);


    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private DoveClient doveClient;

    @Inject
    private UserTagDao userTagDao;
    /**
     * 根据条件获取标签列表
     *
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<TemplateTag> page(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<TemplateTag> result = null;
        FindPage<TemplateTag> findPage = jdbcSession.findPage(TemplateTag.class)
                .eq(jsonObject, "id", "pid")
                .like(jsonObject, "name")
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<TemplateTag> templateTagList = result.getList();
            //设置标签的标签组名称及使用标签用户数
            for (TemplateTag templateTag : templateTagList) {
                QueryCondition query = Condition.createQuery(false);
                query.eq("deleted", false);
                query.order("createTime","desc");
                query.eq("tagNo", templateTag.getId());
                Map<String,Object> countMap = userTagDao.getUserTagCount(query);
                templateTag.setUseCount(Long.parseLong(String.valueOf(countMap.get("count"))));
                TemplateTag templateTagGroup = jdbcSession.findById(TemplateTag.class, templateTag.getPid());
                if (Objects.nonNull(templateTagGroup)) {
                    templateTag.setPname(templateTagGroup.getName());
                } else {
                    templateTag.setPname("");
                }
            }
        }
        return result;
    }

    /**
     * 获取标签列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<TemplateTag> page = page(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签内容
     *
     * @param templateTag 标签对象
     * @return
     */
    @ReqMapping("/get")
    public Object get(TemplateTag templateTag) {
        return templateTag;
    }

    /**
     * 保存标签
     *
     * @param templateTag 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(TemplateTag templateTag) {
        String id = templateTag.getId();
        TemplateTag dbTemplateTag = jdbcSession.findOne(TemplateTag.class)
                .eq("deleted", false)
                .eq("group", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", templateTag.getName()).or()
                .markEnd().exe();
        templateTag.setType(TagSourceType.TEMPLATE_TAG);
        if (Objects.isNull(dbTemplateTag)) {
            templateTag.setGroup(false);
            templateTag.setSort(System.currentTimeMillis());
            templateTag.setType(TagSourceType.TEMPLATE_TAG);
            templateTag.setCreateBy(Root.ROOT_ID);
            templateTag.setCreateName("系统");
            jdbcSession.insert(templateTag);
        } else {
            dbTemplateTag.setName(templateTag.getName());
            templateTag.setCreateBy(Root.ROOT_ID);
            templateTag.setCreateName("系统");
            jdbcSession.updateById(dbTemplateTag);
        }
        return Result.success();
    }

    /**
     * 更新标标签
     *
     * @param templateTag 标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(TemplateTag templateTag) throws Exception {
        String id = templateTag.getId();
        TemplateTag dbTemplateTag = jdbcSession.findOne(TemplateTag.class)
                .eq("group", false)
                .eq("deleted", false)
                .eq("id",id).exe();
        if (Objects.isNull(dbTemplateTag)) {
            return Result.success("0", "标签不存在");
        }
        jdbcSession.updateById(templateTag);
        return Result.success();
    }


    /**
     * 删除标签
     *
     * @param templateTag 标签对象
     * @return
     */
    @ReqMapping("/delete")
    public Object delete(TemplateTag templateTag) {
        templateTag.setDeleted(true);
        jdbcSession.updateById(templateTag);
        return Result.success();
    }

    /**
     * 根据条件获取标签组分页列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/group/page")
    public Page<TemplateTag> groupPage(JSONObject jsonObject) throws Exception {
        //首次查询初始化数据
        firstInitData();
        String tagName = jsonObject.getString("tagName");

        Page<TemplateTag> result = null;
        FindPage<TemplateTag> findPage = jdbcSession.findPage(TemplateTag.class)
                .eq(jsonObject, "id")
                .like(jsonObject, "name")
                .eq("group", true)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        if (Objects.nonEmpty(tagName)) {
            List<TemplateTag> templateTagList = jdbcSession.findArray(TemplateTag.class)
                    .eq("group", false)
                    .eq("deleted", false)
                    .like("name", tagName).exe();
            List<String> ids = templateTagList.stream().map(TemplateTag::getPid).collect(Collectors.toList());
            if (Objects.nonEmpty(ids)) {
                findPage.in("id", ids);
            }
        }
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<TemplateTag> templateTagGroupList = result.getList();
            for (TemplateTag templateGroupTag : templateTagGroupList) {
                List<TemplateTag> templateTagList = jdbcSession.findArray(TemplateTag.class)
                        .eq("pid", templateGroupTag.getId())
                        .eq("group", false)
                        .eq("deleted", false)
                        .order("sort", "desc")
                        .exe();
                //设置标签的组名称
                for (TemplateTag templateTag : templateTagList) {
                    templateTag.setPname(templateGroupTag.getName());
                }
                templateGroupTag.setChildList(templateTagList);
            }
        }
        return result;
    }

    /**
     * 根据条件获取标签组列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/group/list")
    public Object groupList(JSONObject jsonObject) throws Exception {
        //首次查询初始化数据
        firstInitData();
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<TemplateTag> page = groupPage(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签组
     *
     * @param templateTagGroup 系统标签对象
     * @return
     */
    @ReqMapping("/group/get")
    public Object groupGet(TemplateTag templateTagGroup) {
        if (Objects.nonNull(templateTagGroup)) {
            List<TemplateTag> templateTagList = jdbcSession.findArray(TemplateTag.class)
                    .eq("pid", templateTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            templateTagGroup.setChildList(templateTagList);

        }
        return templateTagGroup;
    }

    /**
     * 保存标气标签组及标签
     *
     * @param templateTagGroup 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/group/save")
    public Object groupSave(TemplateTag templateTagGroup) {
        String id = templateTagGroup.getId();
        TemplateTag dbTemplateTagGroup = jdbcSession.findOne(TemplateTag.class)
                .eq("deleted", false)
                .eq("group", true)
                .markBegin()
                .eq("id", id).or()
                .eq("name", templateTagGroup.getName()).or()
                .markEnd().exe();
        templateTagGroup.setType(TagSourceType.TEMPLATE_TAG);
        if (Objects.isNull(dbTemplateTagGroup)) {
            templateTagGroup.setPid(Root.ROOT_ID);
            templateTagGroup.setGroup(true);
            templateTagGroup.setType(TagSourceType.TEMPLATE_TAG);
            templateTagGroup.setSort(System.currentTimeMillis());
            jdbcSession.insert(templateTagGroup);
        } else {
            throw new RuntimeException("标签组不能重复");
/*            dbTemplateTagGroup.setName(templateTagGroup.getName());
            jdbcSession.updateById(dbTemplateTagGroup);*/
        }
        List<TemplateTag> templateTagList = templateTagGroup.getChildList();
        if (Objects.nonNull(templateTagList)) {
            for (TemplateTag templateTag : templateTagList) {
                templateTag.setId(IDGenerate.uuid());
                templateTag.setPid(templateTagGroup.getId());
                templateTag.setGroup(false);
                templateTag.setType(TagSourceType.TEMPLATE_TAG);
                templateTag.setCreateBy(Root.ROOT_ID);
                templateTag.setCreateName("系统");
            }
        }
        jdbcSession.insert(templateTagList);
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param templateTagGroup 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/group/update")
    public Object groupUpdate(TemplateTag templateTagGroup) throws Exception {
        String id = templateTagGroup.getId();
        TemplateTag dbTemplateTagGroup = jdbcSession.findOne(TemplateTag.class)
                .eq("deleted", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", templateTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbTemplateTagGroup)) {
            return Result.success("0", "标签组不存在");
        }
        jdbcSession.updateById(templateTagGroup);


        //输入的标签集合
        List<TemplateTag> templateTagList = templateTagGroup.getChildList();

        Map<String, TemplateTag> mapping = new HashMap<>();
        for (TemplateTag templateTag : templateTagList) {
            if (Objects.nonEmpty(templateTag.getId())) {
                mapping.put(templateTag.getId(), templateTag);
            }
        }


        //数据库已存在的标签集合
        List<TemplateTag> dbTemplateTagList = jdbcSession.findArray(TemplateTag.class)
                .eq("pid", dbTemplateTagGroup.getId())
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .exe();


        //需要更新的标签集合
        List<TemplateTag> updateTemplateTagList = new ArrayList<>();

        //需要删除的标签集合
        List<TemplateTag> deleteTemplateTagList = new ArrayList<>();

        for (TemplateTag dbTemplateTag : dbTemplateTagList) {
            String dbId = dbTemplateTag.getId();
            if (mapping.containsKey(dbId)) {
                updateTemplateTagList.add(mapping.get(dbId));
                templateTagList.remove(dbTemplateTag);
            } else {
                deleteTemplateTagList.add(dbTemplateTag);
            }
        }

        //需要新增的标签集合
        List<TemplateTag> addTemplateTagList = new ArrayList<>(templateTagList);

        //增量新增标签
        if (Objects.nonEmpty(addTemplateTagList)) {
            for (TemplateTag templateTag : addTemplateTagList) {
                templateTag.setId(IDGenerate.uuid());
                templateTag.setPid(dbTemplateTagGroup.getId());
                templateTag.setGroup(false);
                templateTag.setType(TagSourceType.TEMPLATE_TAG);
                templateTag.setCreateBy(Root.ROOT_ID);
                templateTag.setCreateName("系统");
            }
            jdbcSession.insert(addTemplateTagList);
        }

        //增量更新标签
        if (Objects.nonEmpty(updateTemplateTagList)) {
            jdbcSession.updateById(updateTemplateTagList);
        }

        //增量删除标签
        if (Objects.nonEmpty(deleteTemplateTagList)) {
            for (TemplateTag templateTag : deleteTemplateTagList) {
                templateTag.setDeleted(true);
            }
            jdbcSession.updateById(deleteTemplateTagList);
        }
        return Result.success();
    }


    /**
     * 删除标签组及标签
     *
     * @param templateTagGroup 系统标签组对象
     * @return
     */
    @ReqMapping("/group/delete")
    public Object groupDelete(TemplateTag templateTagGroup) {
        templateTagGroup.setDeleted(true);
        jdbcSession.updateById(templateTagGroup);
        if (templateTagGroup.isGroup()) {
            List<TemplateTag> templateTagList = jdbcSession.findArray(TemplateTag.class)
                    .eq("pid", templateTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            if (Objects.nonEmpty(templateTagList)) {
                for (TemplateTag templateTag : templateTagList) {
                    templateTag.setDeleted(true);
                }
                jdbcSession.updateById(templateTagList);
            }
        }
        return Result.success();
    }


    /**
     * 首次初始化模板数据
     * 标签库没有数据，自动触发同步操作
     * @throws Exception
     */
    private void firstInitData() throws Exception{
        JSONObject condition=new JSONObject();
        condition.put("pageSize",1);
        Page<TemplateTag> findPage = jdbcSession.findPage(TemplateTag.class)
                .order("sort", "desc")
                .page(condition).exe();
        List<TemplateTag> templateTagList =findPage.getList();
        if(Objects.isEmpty(templateTagList)){
            condition=new JSONObject();
            reset(condition);
        }
    }
    /**
     * 重置所有模板标签
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/reset")
    public Object reset(JSONObject jsonObject) throws Exception {
        List<TemplateTag> templateTagList = jdbcSession.findArray(TemplateTag.class).eq(jsonObject, "pid").exe();
        jdbcSession.deleteById(templateTagList);
        JSONArray systemTagJSONArray = getSystemTagResetList(jsonObject);
        if (Objects.nonEmpty(systemTagJSONArray)) {
            templateTagList = new ArrayList<>();
            for (Object systemTagJsonObj : systemTagJSONArray) {
                JSONObject systemTagJson = (JSONObject) systemTagJsonObj;
                String id = systemTagJson.getString("id");
                TemplateTag templateTag = Pool.newInstance(TemplateTag.class, id);
                Beans.from(systemTagJson).to(templateTag).exclude("id").igornNull().copy();
                templateTag.setType(TagSourceType.TEMPLATE_TAG);
                templateTagList.add(templateTag);
            }
            jdbcSession.insert(templateTagList);

        }
        return Result.success();
    }

    private JSONArray getSystemTagResetList(JSONObject jsonObject) throws Exception {
        JSONObject systemTagResult = doveClient.post("/admin/sys/tag/service/all", http -> {
            http.setBody(jsonObject.toJSONString());
        });
        return systemTagResult.getJSONArray("data");
    }
}
